﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Diagnostics;

namespace dmm
{
    /// <summary>
    /// Interaction logic for VideoPreview.xaml
    /// </summary>
    public partial class RegionSelector : Window
    {
        private bool showMover = true;
        private bool showCloser = false;

        public bool ShowMover
        {
            get
            {
                return showMover;
            }
            set
            {
                showMover = value;
                if (showMover)
                    mover.Visibility = Visibility.Visible;
                else
                    mover.Visibility = Visibility.Hidden;
            }
        }

        public bool ShowCloser
        {
            get
            {
                return showCloser;
            }
            set{
                showCloser = value;
                if(showCloser)
                    closer.Visibility = Visibility.Visible;
                else
                    closer.Visibility = Visibility.Hidden;
            }
        }

        public static readonly RoutedEvent RegionChangedEvent = EventManager.RegisterRoutedEvent("RegionChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(RegionSelector));

        public event RoutedEventHandler RegionChanged
        {
            add { AddHandler(RegionChangedEvent, value); }
            remove { RemoveHandler(RegionChangedEvent, value); }
        }

        const int CTRL_WIDTH = 5;

        private Rect bound;

        // selected region in 1*1 space
        private Rect region;

        private enum RESIZE_MODE
        {
            RESIZE_TOP = 1,
            RESIZE_BOTTOM = 2,
            RESIZE_LEFT = 4,
            RESIZE_RIGHT = 8,

            RESIZE_TOPLEFT = RESIZE_TOP | RESIZE_LEFT,
            RESIZE_TOPRIGHT = RESIZE_TOP | RESIZE_RIGHT,
            RESIZE_BOTTOMLEFT  = RESIZE_BOTTOM | RESIZE_LEFT,
            RESIZE_BOTTOMRIGHT = RESIZE_BOTTOM | RESIZE_RIGHT
        }

        private RESIZE_MODE resizeFlag = 0;
        private bool bMove = false;

        public Rect Region
        {
            set
            {
                region = value;
                adjust();
               
            }
            get
            {
                return region;
            }
        }


        private void adjust()
        {
            this.Left = bound.Left + region.Left * bound.Width;
            this.Top = bound.Top + region.Top * bound.Height;
            this.Width = region.Width * bound.Width;
            this.Height = region.Height * bound.Height;
        }
        public RegionSelector()
        {
            InitializeComponent();

            region.X = 0;
            region.Y = 0;
            region.Width = 1;
            region.Height = 1;
        }

        public void set_bound(double left, double top, double w, double h)
        {
            bound.X = left;
            bound.Y = top;
            bound.Width =  w;
            bound.Height =  h;
            adjust();
           
        }
        

        private void onMouseMove(object sender, MouseEventArgs e)
        {
            Point p = e.GetPosition(this);

            double w = this.Width;
            double h = this.Height;

            Debug.Write(String.Format("move{0}:{1}\n", p.X, p.Y));
            
            if (e.LeftButton == MouseButtonState.Released)
            {

                if (p.X <= CTRL_WIDTH && p.Y <= CTRL_WIDTH)
                    this.Cursor = Cursors.SizeNWSE;
                else if (p.X <= CTRL_WIDTH && p.Y >= h - CTRL_WIDTH)
                    this.Cursor = Cursors.SizeNESW;
                else if (p.X >= w - CTRL_WIDTH && p.Y >= h - CTRL_WIDTH)
                    this.Cursor = Cursors.SizeNWSE;
                else if (p.X >= w - CTRL_WIDTH && p.Y <= CTRL_WIDTH)
                    this.Cursor = Cursors.SizeNESW;
                else if (p.Y < CTRL_WIDTH || p.Y > h - CTRL_WIDTH)
                    this.Cursor = Cursors.SizeNS;
                else if (p.X < CTRL_WIDTH || p.X > w - CTRL_WIDTH)
                    this.Cursor = Cursors.SizeWE;
                else if (p.X > (w / 2 - 10) && p.X < (w / 2 + 10) && p.Y > (h / 2 - 10) && p.Y < (h / 2 + 10))
                    this.Cursor = Cursors.SizeAll;
                else
                    this.Cursor = Cursors.Arrow;

            }
            else
            {

                if (bMove)
                {
                    p = this.PointToScreen(p);
                    w = this.Width;
                    h = this.Height;

                    var left = p.X - w/2;
                    if(left < bound.X) left = bound.X;
                    if (left > bound.Right - w) left = bound.Right - w; 
                    this.Left = left;

                    var top = p.Y - h / 2;
                    if (top < bound.Y) top = bound.Y;
                    if (top > bound.Bottom - h) top = bound.Bottom - h;
                    this.Top = top;
                    CalcRegion();
                }


                if (resizeFlag!=0)
                {
                    p = this.PointToScreen(p);


                    if (p.X < bound.Left) p.X = bound.Left;
                    if (p.X > bound.Right) p.X = bound.Right;
                    if (p.Y < bound.Top) p.Y = bound.Top;
                    if (p.Y > bound.Bottom) p.Y = bound.Bottom;
                    

                    if ((resizeFlag & RESIZE_MODE.RESIZE_TOP) != 0)
                    {
                        
                        this.Height = this.Height - (p.Y - this.Top);
                        this.Top = p.Y;
                        
                    }
                    if ((resizeFlag & RESIZE_MODE.RESIZE_LEFT) != 0)
                    {
                        this.Width = this.Width - (p.X - this.Left);
                        this.Left = p.X;
                    }
                    if ((resizeFlag & RESIZE_MODE.RESIZE_BOTTOM) != 0) this.Height = p.Y - this.Top;
                    if ((resizeFlag & RESIZE_MODE.RESIZE_RIGHT) != 0) this.Width = p.X - this.Left;

                    CalcRegion();
                    
                }
            }
        }

        private void CalcRegion()
        {
            region.X = (this.Left - bound.Left) / bound.Width;
            region.Width = this.Width / bound.Width;

            region.Y = (this.Top - bound.Top) / bound.Height;
            region.Height = this.Height / bound.Height;

            RaiseEvent(new RoutedEventArgs(RegionSelector.RegionChangedEvent));
        }

        private void onMouseLeftDown(object sender, MouseButtonEventArgs e)
        {
            resizeFlag = 0;

            double w = this.Width;
            double h = this.Height;

            Point point = e.GetPosition(this);

            if (point.X > (w / 2 - 10) && point.X < (w / 2 + 10) && point.Y > (h / 2 - 10) && point.Y < (h / 2 + 10))
            {
                Mouse.Capture(mover);
                bMove = true;
                return;
            }

            if (point.X <= CTRL_WIDTH) resizeFlag |= RESIZE_MODE.RESIZE_LEFT;
            if (point.X >= w - CTRL_WIDTH) resizeFlag |= RESIZE_MODE.RESIZE_RIGHT;
            if (point.Y <= CTRL_WIDTH) resizeFlag |= RESIZE_MODE.RESIZE_TOP;
            if (point.Y >= h - CTRL_WIDTH) resizeFlag |= RESIZE_MODE.RESIZE_BOTTOM;
            if (resizeFlag != 0) Mouse.Capture(border);
        }

        private void onMouseLeftUp(object sender, MouseButtonEventArgs e)
        {
            bMove = false;
            resizeFlag = 0;
            Mouse.Capture(null);
        }


        private void onClose(object sender, RoutedEventArgs e)
        {
            this.Close();
        }


       /* private void onOverMover(object sender, RoutedEventArgs e)
        {
            this.Cursor = Cursors.SizeAll;
        }*/



      
    }
}
